package org.performancetracker;

import org.performancetracker.api.Aggregator;
import org.performancetracker.simple.AggregatorImpl;

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Basic implementation of TrackerAggregatorFactory.
 *
 * Uses a map to keep a cashe of previously used aggregators with the same name.
 *
 * @author: jaronschut
 */

public class AggregatorFactoryImpl {

    /* ConcurrentHashMap is used to limit the scope of synchronization */
    private static final ConcurrentMap<String, Aggregator> aggregatorMap = new ConcurrentHashMap<String, Aggregator>();

    /**
     * Thread safe method to retrieve and possibly create a tracker aggregator.
     * 2 or more threads calling for an aggregator with the same name should allways get the same aggregator object.
     *
     * @param aggregatorName
     * @return
     */
    public Aggregator createTrackerAggregator(String aggregatorName) {
        assert(aggregatorName != null);

        Aggregator aggregator = null;

        while ((aggregator = aggregatorMap.get(aggregatorName)) == null) {
            aggregator = new AggregatorImpl(aggregatorName);
            aggregatorMap.putIfAbsent(aggregatorName, aggregator);
        }

        return aggregator;
    }
	/**
	 * Thread safe method to retrieve and possibly create the default tracker aggregator.
	 * 2 or more threads calling for an aggregator with the same name should allways get the same aggregator object.
	 *
	 * @return
	 */
	public static Aggregator getDefaultTrackerAggregator() {

        Aggregator aggregator = null;

        while ((aggregator = aggregatorMap.get(Aggregator.DEFAULT_AGGREGATOR_NAME)) == null) {
            aggregator = new org.performancetracker.simple.AggregatorImpl(Aggregator.DEFAULT_AGGREGATOR_NAME);
            aggregatorMap.putIfAbsent(Aggregator.DEFAULT_AGGREGATOR_NAME, aggregator);
        }

        return aggregator;
	}
}
